package com.googlecode.bip.chart;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;

/**
 * com.googlecode.bip.chart.ChartServlet
 *
 * @author Claude CHOISNET
 */
public class ChartServlet extends HttpServlet
{
    private final static transient Logger logger = Logger.getLogger( ChartServlet.class );
    private static final long serialVersionUID = 1L;
    /** Request parameter for chart Name : {@value} */
    public static final String CHARTNAME = "ChartName";
    private ChartConfig defaultChartConfig;

    @Override
    public void init( ServletConfig servletConfig ) throws ServletException
    {
        ChartConfigImpl chartConfig = new ChartConfigImpl();

        this.defaultChartConfig = chartConfig;

        chartConfig.setWidth( getInitParameterInteger( servletConfig, "width" ) );
        chartConfig.setHeight( getInitParameterInteger( servletConfig, "height" ) );
        chartConfig.setEncodeAlpha( getInitParameterBoolean( servletConfig, "encodealpha" ) );
        chartConfig.setCompression( getInitParameterInteger( servletConfig, "compression" ) );

        logger.info( "servlet " + servletConfig.getServletName() + " initialized with " + chartConfig );
    }

    private String getInitParameter( ServletConfig servletConfig, String name )
        throws ServletException
    {
        String value = servletConfig.getInitParameter( name );

        if( value == null ) {
            throw new ServletException( "Servlet parameter '" + name + "' not found" );
            }

        return value;
    }

    private Integer getInitParameterInteger( ServletConfig servletConfig, String name )
        throws ServletException
    {
        String value = getInitParameter( servletConfig, name );

        try {
            int ivalue = Integer.parseInt( value );

            return ivalue;
            }
        catch( NumberFormatException e ) {
            throw new ServletException( "Servlet parameter '" + name + "' is not an integer" );
            }
    }

    private Boolean getInitParameterBoolean( ServletConfig servletConfig, String name )
        throws ServletException
    {
        String value = getInitParameter( servletConfig, name );

        return new Boolean( value );
    }

    @Override
    public void service( HttpServletRequest request, HttpServletResponse response )
        throws IOException
    {
        HttpSession session = request.getSession();
        String      errMsg  = null;

        if( session != null ) {
            // TODO: Improve this
            String chartName = request.getParameter( CHARTNAME );

            if( chartName != null ) {
                Object chartObject = session.getAttribute( chartName );

                if( chartObject instanceof JFreeChart ) {
                    JFreeChart  chart       = (JFreeChart)chartObject;

                    displayChart( chart, response );

                    return; // done !
                    }
                else {
                    errMsg = "No JFreeChart on session with name ='" + chartName + "'";
                    logger.warn( errMsg );
                    }
                }
            else {
                errMsg = "Not parameter " + CHARTNAME;
                logger.warn( errMsg );
                }
            }
        else {
            errMsg = "no session";
            logger.warn( errMsg );
            }

        // TODO: display in picture !
        PrintWriter out = response.getWriter();
        out.println("Error : " + errMsg );
        out.close();
    }


    protected void displayChart(JFreeChart chart, HttpServletResponse response)
        throws IOException
    {
        //TODO: allow custom CharConfig on session
        ChartConfig chartConfig = this.defaultChartConfig;

        final String mimeType = "image/png";

        response.setHeader( "Content-Type", mimeType );

        BufferedOutputStream bos = new BufferedOutputStream( response.getOutputStream());

        writeChart( bos, chart, chartConfig );

        bos.flush();
        bos.close();
    }

    protected static void writeChart(
            OutputStream    out,
            JFreeChart      chart,
            ChartConfig     chartConfig
            )
        throws IOException
    {
        ChartUtilities.writeChartAsPNG( out, chart, chartConfig.getWidth(), chartConfig.getHeight(), chartConfig.isEncodeAlpha(), chartConfig.getCompression() );
    }

    /**
     *
     * @param request
     * @param response
     * @param servletURL
     * @param chartName
     * @return
     */
    public static String createChartURLString(
            HttpServletRequest  request,
            HttpServletResponse response,
            final String        servletURL,
            final String        chartName
            )
    {
        return response.encodeURL(
                request.getContextPath() + servletURL + "?" + CHARTNAME + "=" + chartName
                );
    }

}
